<template>
  <div>
    <div class="wrapper">
      <div class="left">
        <draggable v-model="arr1" :options="{ group: { name: 'itxst', pull: 'clone', put: false, }, sort: false }"
          animation="300" :move="onMove">
          <transition-group class="left-group">
            <div class="item flex-item" v-for="item in arr1" :key="item.id" @mouseenter="mouseEnter(item)">
              <div class="flex-item-item">
                <label class="move">{{ item.name }}</label><a-icon :type="item.icon" />
              </div>
            </div>
          </transition-group>
        </draggable>
      </div>
      <div class="center">
        <div class="left right">
          <draggable v-model="arr2" group="itxst" animation="300"
            :options="{ group: { name: 'itxst', pull: false }, sort: false }" @add="onAdd">
            <transition-group class="group" :style="style">
              <div class="item" v-for="(item, index) in arr2" :key="item.id">
                <div class="right-item" :class="{ 'active': selectedIndex === index, 'item': true }"
                  @mouseenter="handleMouseEnter(item)" @mouseleave="handleMouseLeave(item)"
                  @click="rightClick(index, item)">
                  <label>{{ item.name }}</label>
                  <div class="item-body">
                    <span>{{ item.desc }}</span>
                    <a-icon :type="item.icon2" />
                    <a-icon type="close" class="icon-pos" v-show="item.show" @click="handleClick(item, 'right')" />
                  </div>
                </div>
              </div>
            </transition-group>
          </draggable>
        </div>
      </div>

      <div>
        <a-drawer :title="title" placement="right" :closable="false" :visible="visible" @close="onClose" :mask="false"
          width="400" closable>
          <a-form id="form" :form="form" @submit="handleSubmit">
            <a-form-item label="字段名称">
              <a-input v-decorator="[
                'name',
                {
                  rules: [{ required: true, message: '字段名称不能为空!' }],
                },
              ]" @input="handleNameInput" />
            </a-form-item>
            <a-form-item label="提示文字">
              <a-input v-decorator="[
                'placeholder',
              ]" @input="handlePlaceholderInput" />
            </a-form-item>

            <a-form-item label="选项" v-if="addType == 'select'">
              <a-form-item v-for="(k, index) in form.getFieldValue('keys')" :key="k" :required="false">
                <a-input v-decorator="[
                  `names[${k}]`
                ]
                  " placeholder="请输入" style="width: 90%; margin-right: 8px" />
                <a-icon v-if="form.getFieldValue('keys').length > 1" class="dynamic-delete-button" type="minus-circle-o"
                  :disabled="form.getFieldValue('keys').length === 1" @click="() => remove(k)" />
              </a-form-item>
              <a-form-item v-bind="formItemLayoutWithOutLabel">
                <a-button type="dashed" style="width: 60%" @click="add">
                  <a-icon type="plus" /> 添加
                </a-button>
              </a-form-item>
            </a-form-item>
            <!-- <a-form-item v-bind="formItemLayoutWithOutLabel">
              <a-button type="primary" @click="typeOpt">
                typeOpt
              </a-button>
            </a-form-item> -->


            <a-form-item label="字符类型" v-if="addType == 'text'">
              <a-radio-group v-decorator="['type']">
                <a-radio value="number">
                  数字
                </a-radio>
                <a-radio value="zh">
                  中文
                </a-radio>
                <a-radio value="en">
                  英文
                </a-radio>
                <a-radio value="any">
                  不限制
                </a-radio>
                <a-radio value="float">
                  小数
                </a-radio>
              </a-radio-group>
            </a-form-item>
            <a-form-item label="字符长度" v-if="addType == 'text'">
              <a-form-item :label-col="{ span: 7 }" :wrapper-col="{ span: 12 }" label="字符最长">
                <a-input-number v-decorator="['maxLength', {
                  rules: [{ required: true, message: '请输入最长字符!' }],
                }]" :min="1" @change="handleMaxChange" />
              </a-form-item>
              <a-form-item :label-col="{ span: 7 }" :wrapper-col="{ span: 12 }" label="字符最短">
                <a-input-number v-decorator="['minLength', {
                  rules: [{ required: true, message: '请输入最短字符!' }],
                  initialValue: 1
                }]" :min="1" @change="handleMinChange" />
              </a-form-item>
            </a-form-item>

            <a-form-item label="设置列宽">
              <a-input-number v-decorator="['labelWidth', {
                rules: [{ required: true, message: '请设置列宽!' }],
                initialValue: 200
              }]" :min="1" />
            </a-form-item>
            <a-form-item label="日期类型" v-if="addType == 'date'">
              <a-radio-group v-decorator="['date']">
                <a-radio value="month">
                  年 - 月
                </a-radio>
                <a-radio value="day">
                  年 - 月 - 日
                </a-radio>
                <a-radio value="time">
                  年 - 月 - 日 时 - 分
                </a-radio>
              </a-radio-group>
            </a-form-item>
            <a-form-item label="是否必填">
              <a-radio-group v-decorator="['isRequired']">
                <a-radio value="y">
                  必填
                </a-radio>
                <a-radio value="n">
                  非必填
                </a-radio>
              </a-radio-group>
            </a-form-item>
          </a-form>
        </a-drawer>
      </div>
    </div>
    <a-button @click="handleCreate">创建</a-button>
    <a-button @click="handleClean">清除缓存</a-button>
    <a-modal v-model="visibleModal" title="表单生成" @ok="handleOk">
      <a-form layout="horizontal" id="components-form-demo-validate-other" :form="modalForm" @submit="handleSubmit">
        <a-form-item v-for="item in  formData " :key="item.id" :label="item.name">
          <a-radio-group v-if="item.val == 'radio'" v-decorator="['dataForm.radio', {
            rules: [{ required: item.conf.isRequired == 'y' ? true : false, message: '必选' }]
          }]" :options="item.conf.opt">
          </a-radio-group>
          <a-checkbox-group :options="item.conf.opt" v-else-if="item.val == 'checkbox'" v-decorator="['dataForm.checkedList', {
            rules: [{ required: item.conf.isRequired == 'y' ? true : false, message: '必选' }],
          }]" />
          <a-input-number v-else-if="item.val == 'text' && item.conf.type == 'number'" v-decorator="['dataForm.text', {
            rules: [{ required: item.conf.isRequired == 'y' ? true : false, message: '必填' }],
          }]" :min="item.conf.minLength" :max="item.conf.maxLength" />
          <a-input v-else-if="item.val == 'text'" v-decorator="['dataForm.text', {
            rules: [{ required: item.conf.isRequired == 'y' ? true : false, message: '必填' }],
          }]" :placeholder="item.desc" @input="handleModalInput($event, item.conf)" :maxLength="item.conf.maxLength" />
          <a-textarea v-else-if="item.val == 'textarea'" v-decorator="['dataForm.textarea', {
            rules: [{ required: item.conf.isRequired == 'y' ? true : false, message: '必填' }],
          }]" :placeholder="item.desc" :maxLength="item.conf.maxLength" />
          <a-date-picker v-else-if="item.val == 'date' && item.conf.date == 'day'" v-decorator="['dataForm.date',
            { rules: [{ type: 'object', required: item.conf.isRequired == 'y' ? true : false, message: '必选' }] }
          ]" :placeholder="item.desc" />
          <a-date-picker show-time v-else-if="item.val == 'date' && item.conf.date == 'time'" v-decorator="['dataForm.date',
            { rules: [{ type: 'object', required: item.conf.isRequired == 'y' ? true : false, message: '必选' }] }
          ]" :placeholder="item.desc" />
          <a-month-picker v-else-if="item.val == 'date' && item.conf.date == 'month'" v-decorator="['dataForm.date',
            { rules: [{ type: 'object', required: item.conf.isRequired == 'y' ? true : false, message: '必选' }] }
          ]" :placeholder="item.desc" />
          <a-upload v-else-if="item.val == 'img'" name="avatar" list-type="picture-card" class="avatar-uploader"
            :show-upload-list="false" action="https://www.mocky.io/v2/5cc8019d300000980a055e76" v-decorator="['dataForm.img', {
              rules: [{ required: item.conf.isRequired == 'y' ? true : false, message: '必传' }],
            }]">
            <img v-if="imageUrl" :src="imageUrl" alt="avatar" />
            <div v-else>
              <div class="ant-upload-text">
                Upload
              </div>
            </div>
          </a-upload>
          <a-upload v-else name="file" :multiple="true" action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
            v-decorator="['dataForm.path', {
              rules: [{ required: item.conf.isRequired == 'y' ? true : false, message: '必传' }],
            }]">
            <a-button> <a-icon type="upload" /> Click to Upload </a-button>
          </a-upload>
        </a-form-item>
      </a-form>
    </a-modal>
  </div>
</template>

<script>
import draggable from 'vuedraggable';
export default {
  name: 'Draggable',
  props: {

  },
  components: {
    draggable
  },
  data() {
    return {
      formItemLayout: {
        labelCol: {
          xs: { span: 24 },
          sm: { span: 4 },
        },
        wrapperCol: {
          xs: { span: 24 },
          sm: { span: 20 },
        },
      },
      formItemLayoutWithOutLabel: {
        // wrapperCol: {
        //   xs: { span: 24, offset: 0 },
        //   sm: { span: 20, offset: 4 },
        // },
      },
      arr1: [
        { id: 3, name: '单选下拉框', val: 'radio', icon: 'down-circle', icon2: 'right', desc: "请选择", show: false },
        { id: 4, name: '多选下拉框', val: 'checkbox', icon: 'down-square', icon2: 'right', desc: "请选择", show: false },
        { id: 5, name: '单行文本', val: 'text', icon: 'font-colors', icon2: 'right', desc: "请输入", show: false },
        { id: 6, name: '多行文本', val: 'textarea', icon: 'font-size', icon2: 'right', desc: "请输入", show: false },
        { id: 7, name: '选择档案', val: 'upload', icon: 'database', icon2: 'right', desc: "请输入", show: false },
        { id: 8, name: '图片', val: 'img', icon: 'file-image', icon2: 'right', desc: "请上传", show: false },
        { id: 9, name: '日期', val: 'date', icon: 'calendar', icon2: 'right', desc: "请选择", show: false },
        { id: 10, name: '关联档案', val: 'upload', icon: 'file-text', icon2: 'right', desc: "请输入", show: false },
      ],
      arr2: [
        // { id: 1, name: '终端名称', icon: 'file-text', icon2: 'right', desc: "请输入", show: false },
        // { id: 2, name: '产品名称', icon: 'file-text', icon2: 'right', desc: "请输入", show: false },
      ],
      style: {
        minHeight: '50vh',
        display: "block",
        backgroundColor: '#f3f3f3',
      },
      cache: {},
      temp: {},
      selectedIndex: null,
      visible: false,
      visibleModal: false,
      title: null,
      formLayout: 'horizontal',
      form: this.$form.createForm(this, { name: 'coordinated' }),
      // form: {},
      modalForm: this.$form.createForm(this, { name: 'validate_other' }),
      // modalForm: {},
      dataForm: {
        text: null,
        textarea: null,
        date: null,
        img: null,
        path: null,
        checkedList: []
      },
      addType: null,
      checkedList: [],
      formData: [],
      imageUrl: [],
      dataList: [],
    }
  },
  beforeCreate() {
    // this.form = this.$form.createForm(this, { name: 'dynamic_form_item' });
    // this.form.getFieldDecorator('keys', { initialValue: [], preserve: true });
    // this.modalForm = this.$form.createForm(this, { name: 'validate_other' });
  },
  methods: {
    mouseEnter(e) {
      this.cache = e
    },
    handleMouseEnter(e) {
      (e.id != 1 && e.id != 2) ? e.show = true : e.show = false
    },
    handleMouseLeave(e) {
      e.show = false
    },
    handleClick(item, type) {
      if (type == 'right') {
        if (window.confirm("是否确认删除?")) {
          this.arr2.splice(this.arr2.indexOf(item), 1);
        }
      }
    },
    onMove(e) {
      this.cache = e.draggedContext.element
      return true;
    },
    generateUniqueId() {
      return Math.random().toString(36).substring(2)
    },
    onAdd(e) {
      const ori = { ...this.cache };
      const newItemId = this.generateUniqueId();
      Object.assign(ori, { id: newItemId });
      this.arr2.splice(e.newIndex, 1, ori);
    },
    rightClick(e, item) {
      this.temp = item
      this.selectedIndex = e;
      const arr = JSON.parse(localStorage.getItem('formData'))
      const ori = arr && arr.filter(i => {
        if (i.id == item.id) { return i }
      })
      if (this.visible == true) {
        this.onClose()
        return
      }
      if (ori && ori.length != 0) {
        this.form.resetFields()
        const field = ["name", "isRequired", "placeholder", "type", "minLength", "maxLength", "date", "keys"]
        const obj = ori[0].conf
        if (obj.name.includes("下拉框")) {
          this.addType = "select"
        } else if (obj.name == '日期') {
          this.addType = "date"
        } else {
          this.addType = "text"
        }
        // console.log("vlaue", obj)
        for (const key in obj) {
          if (field.includes(key)) {
            console.log("key", key, obj[key], obj)
            // if (key == "keys") {
            // this.form.getFieldDecorator(key, { initialValue: obj.opt, preserve: true });
            //   this.form.getFieldDecorator(key, { initialValue: obj[key], preserve: true });
            // } else {
            // this.$nextTick(() => {
            this.form.getFieldDecorator(key, { initialValue: obj[key], preserve: true });
            // })
            // this.form.getFieldDecorator(key, { initialValue: obj[key], preserve: true });
            // }
            this.$forceUpdate()
          }
        }
        this.$forceUpdate()
        setTimeout(() => {
        this.visible = true
        }, 300);
      } else {
        this.form.resetFields()
        if (item.name.includes("单选下拉框")) {
          this.addType = "select"
          this.visible = true
          this.$nextTick(() => {
            this.form = this.$form.createForm(this, { name: 'dynamic_form_item' });
            this.form.getFieldDecorator('keys', { initialValue: ['选项1', '选项2', '选项3'], preserve: true });
          });
        } else if (item.name.includes("多选下拉框")) {
          this.addType = "select"
          this.visible = true
          this.$nextTick(() => {
            this.form = this.$form.createForm(this, { name: 'dynamic_form_item' });
            this.form.getFieldDecorator('keys', { initialValue: ['选项一', '选项二', '选项三'], preserve: true });
          });
        } else if (item.name == '日期') {
          this.addType = "date"
          this.visible = true
          this.$nextTick(() => {
            this.form = this.$form.createForm(this, { name: 'dynamic_form_item' });
            this.form.getFieldDecorator('date', { initialValue: 'month', preserve: true });
          });
        } else {
          this.addType = "text"
          this.visible = true
          this.$nextTick(() => {
            this.form = this.$form.createForm(this, { name: 'dynamic_form_item' });
            this.form.getFieldDecorator('type', { initialValue: 'number', preserve: true });
            // this.form.getFieldDecorator('minLength', { initialValue: 1, preserve: true });
          });
        }
        this.$nextTick(() => {
          this.form.getFieldDecorator('name', { initialValue: item.name, preserve: true });
          this.form.getFieldDecorator('isRequired', { initialValue: 'y', preserve: true });
          this.form.getFieldDecorator('placeholder', { initialValue: item.desc, preserve: true });
          this.$forceUpdate()
        });
      }
    },
    handleNameInput() {
      this.temp.name = this.form.getFieldValue('name')
    },
    handleMaxChange(value) {
      // this.form.setFieldsValue({ 'maxLength': value })
      const min = this.form.getFieldValue('minLength')
      if (min > value) {
        this.form.setFieldsValue({ 'minLength': value })
      }
    },
    handleMinChange(value) {
      const max = this.form.getFieldValue('maxLength')
      if (max < value) {
        this.form.setFieldsValue({ 'maxLength': value })
      }
    },
    handlePlaceholderInput() {
      this.temp.desc = this.form.getFieldValue('placeholder')
    },
    remove(k) {
      const { form } = this;
      const keys = form.getFieldValue('keys');
      if (keys.length === 1) {
        return;
      }
      form.setFieldsValue({
        keys: keys.filter(key => key !== k),
      });
    },

    add() {
      const { form } = this;
      const keys = form.getFieldValue('keys');
      const nextKeys = keys.concat(`选项${keys.length + 1}`);
      form.setFieldsValue({
        keys: nextKeys,
      });
      this.$forceUpdate()
    },
    handleModalInput(e, t) {
      if (t.type == "zh") {
      } else if (t.type == "en") {
        e.target.value = e.target.value.replace(/[^a-zA-Z]/g, '');
      } else if (t.type == "float") {
      } else {
      }
      if (e.target.value > t.maxLength) {
        e.target.value = e.target.value.slice(0, t.maxLength)
        this.modalForm.setFieldsValue({
          'text': e.target.value,
        });
        this.$message.warning(`请输入${t.maxLength}位以内的字符`)
      }

    },

    typeOpt() {
      return this.form.validateFields((err, values) => {
        if (!err) {
          const { keys, names } = values;
          console.log('keys: ', keys, 'names: ', names)
          console.log('Received values of form: ', values);
          console.log(
            'Merged values:',
            keys.map(key => names[key]),
          );
          return keys.map(key => names[key])
        }
      });
    },
    handleOk(e) {
      this.modalForm.validateFields((err, values) => {
        if (!err) {
          console.log('表单值', values);
          console.log('配置值', JSON.parse(localStorage.getItem('formData')));
        }
      });

      // this.visibleModal = false;
    },
    onClose() {
      this.temp.conf = this.form.getFieldsValue()
      const { names } = this.form.getFieldsValue()
      if (names) {
        const opt = Object.keys(names).map(key => ({
          label: names[key] || key,
          value: key
        }));
        this.temp.conf.opt = opt || []
        this.temp.conf.names = names || {}
      }



      //  this.dataList = [{ id: 1 }, { id: 2 }, { id: 3 }];
      // const replacement = { id: 2, newProperty: "newValue" }; // 替换的新对象


      if (this.dataList.length == 0) { this.dataList = [this.temp]; }

      const index = this.dataList.findIndex(item => item.id === this.temp.id);
      if (index !== -1) {
        this.dataList[index] = this.temp;
      } else {
        this.dataList = [...this.dataList, this.temp];
      }



      // const uniqueArray = Array.from(
      //   new Map(this.dataList.map(item => [item.id, item])).values()
      // );
      // this.dataList = uniqueArray


      // if (this.dataList.length == 0) { this.dataList = [this.temp]; }
      // const index = this.dataList.findIndex(element => {
      //   return element.id === this.temp.id
      // });
      // console.log(index, "index")
      // if (index != -1) {
      //   this.dataList.splice(index, 1, this.temp)
      // } else {
      //   this.dataList = [...this.dataList, this.temp];
      // }



      // if (this.dataList.length == 0) { this.dataList = [this.temp]; console.log(1111111) }
      // console.log(this.dataList, 890)
      // const index = this.dataList.findIndex(element => {
      //   return element.id === this.temp.id
      // });
      // console.log(index, "index")
      // if (!flag) {
      // this.dataList = [...this.dataList, this.temp];
      //   // this.dataList.push(this.temp)
      // }
      // if(index != -1){
      //   this.dataList.splice(index, 1, this.temp)
      // }else{
      //   this.dataList = [...this.dataList, this.temp];
      // }

      // const { names } = this.form.getFieldsValue()
      // if (names) {
      //   const opt = Object.keys(names).map(key => ({
      //     label: names[key] || key,
      //     value: key
      //   }));
      //   this.temp.conf.opt = opt || []
      //   this.temp.conf.names = names || {}
      // }
      ///////////
      // this.temp.conf = this.form.getFieldsValue()
      // this.temp.conf.opt = opt
      this.visible = false;
      console.log(this.temp, "temp")
      console.log(this.dataList, "dataList")
    },

    handleCreate() {
      // console.log(this.dataList, "this.dataList")
      if (this.dataList.length == 0) {
        this.$message.warning(`请先完善信息`)
        return
      }
      // console.log(this.dataList, 111)
      console.log(this.arr2, 111)
      let flag = false
      this.dataList.forEach((i, inx) => {
        // this.arr2.forEach((i, inx) => {
        // this.arr2.filter((i, inx) => {
        // this.dataList.filter((i, inx) => {
        if (!i.name) {
          this.$message.warning(`请完善字段名`)
          flag = true
        }
        if (!i.conf) {
          this.$message.warning(`请完善${i.name}字段信息`)
          flag = true
        }
        if (i.conf && !i.conf.labelWidth) {
          this.$message.warning(`请完善${i.name}信息的设置列宽`)
          flag = true
        }
        if (i.name.includes("文本") && i.conf) {
          console.log(44444)
          console.log("chang:", i.conf.maxLength)
          console.log("short:", i.conf.minLength)

          if (i.conf.minLength == undefined || i.conf.minLength == '') {
            this.$message.warning(`请完善${i.name}信息的字符最短`)
            flag = true
          }
          if (i.conf.maxLength == undefined || i.conf.maxLength == '') {
            this.$message.warning(`请完善${i.name}信息的字符最长`)
            flag = true
          }
        }
        //////////////////
        // if (i.name.includes("文本") && i.conf && !i.conf.minLength ) {
        //   // console.log(i.conf)
        //   // console.log(i.conf.minLength)
        //   // console.log(!!!i.conf.minLength)
        //   this.$message.warning(`请完善${i.name}信息的字符最短`)
        //   flag = true
        // }

        // if (i.name.includes("文本") && i.conf && !i.conf.maxLength) {
        // // if (i.name.includes("文本") && i.conf && i.conf.maxLength != 'undefined' || i.conf.maxLength != '') {
        //   console.log(i.name.includes("文本") && i.conf && i.conf.maxLength != 'undefined' || i.conf.maxLength != '')
        //   console.log(i.name.includes("文本") && i.conf && !i.conf.maxLength )
        //   console.log(i.conf.maxLength)
        //   console.log(!!i.conf.maxLength)
        //   this.$message.warning(`请完善${i.name}信息的字符最长`)
        //   flag = true
        // }
      })
      if (flag) return
      // localStorage.setItem('formData', JSON.stringify(this.arr2))
      localStorage.setItem('formData', JSON.stringify(this.dataList))
      this.visibleModal = true;
      this.formData = this.dataList
      // this.formData = JSON.parse(localStorage.getItem('formData'))
      // this.dataList = []
    },
    handleClean(e) {
      localStorage.removeItem('formData')
      this.dataList = []
    },
    handleClone(e) {
      console.log(e, 111)
    },
    handleSubmit(e) {
      console.log(e, 111)
    },
    normFile(e) {
      console.log('Upload event:', e);
      if (Array.isArray(e)) {
        return e;
      }
      return e && e.fileList;
    },
  },
}
</script>
<style scoped>
.wrapper {
  display: flex;

}

.center {
  position: relative;
  width: 40vw;
}

.left {
  width: 20vw;
  height: 90vh;
  background-color: #fff;
  margin: 10px;
  padding: 10px;
  border-radius: 5px;
}

.right {
  width: 300px;
  /* width: 15vw; */
  height: 60vh;
  border-radius: 30px;
  background-color: #fff;
  position: absolute;
  right: 20px;
  top: 20px;
}

.group {
  border-color: #66b1ff;
}

.left-group {
  border-color: #66b1ff;
  display: flex;
  width: 20vw;
  flex-wrap: wrap;

}

.flex-item {
  flex: 0 0 50%;
  box-sizing: border-box;
  padding: 10px;

}

.flex-item-item {
  border: 1px solid;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 5px;
  border-radius: 3px;
  width: 8vw;
  cursor: move;
}

.right-item {
  border: 1px solid #eee;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px;
  width: 100%;
  background: #fff;
  margin: 10px 0;
}

.right-item:hover {
  border: 1px dotted #14ce90;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px;
  width: 100%;
  background: #fff;
  margin: 10px 0;
}

.item-body {
  position: relative;
}

.icon-pos {
  position: absolute;
  top: -10px;
}

.move {
  cursor: move;
}

.active {
  border: 1px solid #14ce90 !important;
}
</style>
 